package ru.spb.nicetu.altx.mnemo.utils.xmlsettings;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Element;
import org.xml.sax.SAXException;

public abstract class AFileDomSettingsDocument extends ABaseDomSettingsDocument {

  private DocumentBuilder m_builder;


  public AFileDomSettingsDocument(boolean forceInit) {
    super(null);

    try {
      m_builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
      m_document = m_builder.newDocument();
    } catch (ParserConfigurationException e) {
      e.printStackTrace();
    }
    if (forceInit)
      init();
  }

  @Override
  public InputStream toStream() {
    try {
      OutputStream os = new ByteArrayOutputStream();
      Transformer t = TransformerFactory.newInstance().newTransformer();
      t.setOutputProperty("indent", "yes");
      t.transform(new DOMSource(m_document), new StreamResult(os));
      return new ByteArrayInputStream(os.toString().getBytes());
    } catch (TransformerConfigurationException e) {
      e.printStackTrace();
    } catch (TransformerFactoryConfigurationError e) {
      e.printStackTrace();
    } catch (TransformerException e) {
      e.printStackTrace();
    }
    return null;
  }

  @Override
  protected void updateSchemaFile() {
    try {
      InputStream stream = toStream();
      File xmlFile = getExistingXMLLFile();
      FileOutputStream outStream = new FileOutputStream(xmlFile, false);

      int off = 0;
      int len = 255;
      byte[] buf = new byte[len + 1];

      int cnt = 0;
      cnt = stream.read(buf, off, len);
      if (cnt == -1)
        return;

      do {
        outStream.write(buf, 0, cnt);
        cnt = stream.read(buf, off, len);
      } while (cnt != -1);
    } catch (Exception e) {
      e.printStackTrace();
    }
    /*
     * if (file.exists()) { file.setContents(stream, true, true, null); } else {
     * file.create(stream, true, null); } stream.close(); } catch
     * (FileNotFoundException e) { e.printStackTrace(); } catch (CoreException
     * e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace();
     * }
     */
  }


  abstract protected File getExistingXMLLFile();

//  private FileOutputStream getOutputStream() {
//    File settingsDir = m_workspaceRoot.getLocation().append(SETTINGS_DIR).toFile();
//    if (!settingsDir.exists())
//      settingsDir.mkdirs();
//
//    File ioFile = m_workspaceRoot.getLocation().append(SETTINGS_DIR).append(FILE_NAME).toFile();
//    if (!ioFile.exists()) {
//      ioFile.createNewFile();
//    }
//    return ioFile;
//  }

  protected void init() {
    File ioFile = getExistingXMLLFile();
//    File ioFile = m_workspaceRoot.getLocation().append(SETTINGS_DIR).append(FILE_NAME).toFile();

    boolean good = ioFile.exists();
    if (good) {
      try {
        good = false;
        m_document = m_builder.parse(new FileInputStream(ioFile));
        good = true;
      } catch (SAXException e) {
      } catch (IOException e) {
      }
    }

    if (!good) {
      Element seance = m_document.createElement(ROOT_TAG_NAME);
      m_document.appendChild(seance);

      updateSchemaFile();
    }
  }

}
